/**
 *
 */
package com.block.common.util;

import cn.hutool.core.util.StrUtil;
import com.block.db.util.IdTypeEnum;
import com.block.db.util.SnowflakeUtil;

import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 
 * 字符串相关工具
 */
public class StringUtil {
    /**
     * 替换空格的正则表达式
     */
    public static final String REPLACE_BLANK_REGEX="\\s*|\t|\r|\n";
    /**
     * 通过【字符串对象】返回字符串
     * @param strObject
     * @return
     * 2017年7月5日 下午8:44:56
     */
    public static String getStr(Object strObject) {
        return strObject != null ? strObject.toString() : "";
    }

    /**
     * 从带区号的手机号中 截取 不带区号的 手机号
     * @param areaMobile
     * @param areaCode
     * @return
     */
    public static String getMobileFromAreaMobile(String areaMobile, String areaCode){
        if (StrUtil.isEmpty(areaCode) || StrUtil.isEmpty(areaMobile)){
            return areaMobile;
        }
        return areaMobile.substring(StrUtil.length(areaCode));
    }

    /**
     * 截取一定数量字节的字符串
     * @param message
     * @param byteNum
     * @return
     */
    public static String subByteByNum(String message, Integer byteNum){
        int total = 0;
        StringBuilder builder = new StringBuilder();
        for (int index=0; index<message.length(); index++){
            String msg = message.substring(index, index + 1);
            int i = StrUtil.byteLength(msg, Charset.forName("UTF-8"));
            if ((total + i) > byteNum){
                break;
            }
            total += i;
            builder.append(msg);
        }
        return builder.toString();
    }

    /**
     * 生成流水号（唯一）
     * 【29位】
     * @return
     */
    public static String getSerilNum() {
        String serlNum = "";
        int random = (int) (Math.random() * 9) + 10;
        serlNum = String.valueOf(Math.abs(UUID.randomUUID().toString()
                .hashCode()));
        String str = "0000000000";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmsssss");
        String nowStr = sdf.format(new Date());
        if (serlNum.length() > 10) {
            serlNum = serlNum.substring(0, 10);
        } else if (serlNum.length() < 10) {
            serlNum = serlNum + str.substring(serlNum.length());
        }
        serlNum = nowStr + random + serlNum;
        return serlNum;
    }

    public static String getUUID() {
        return UUID.randomUUID().toString().replace("-", "").toUpperCase();
    }

    public static String getBirthdayFromIdCard(String idCard) {
        if (org.springframework.util.StringUtils.isEmpty(idCard) || idCard.length() != 18) {
            return "";
        }
        String year = idCard.substring(6, 10);
        String month = idCard.substring(10, 12);
        String day = idCard.substring(12, 14);
        return String.format("%s-%s-%s", year, month, day);
    }

    /**
     * 过时,改使用SnowflakeUtil
     * @see com.block.db.util.SnowflakeUtil
     * 生成流水号（唯一）
     * 【年月日时分秒】+【uuid(位数不够，随机数字字母补位)】
     * 【至少大于十四位】
     * @return
     */
    @Deprecated
    public static String getSerilNumByLength(int length) {
        if (length <= 14) {
            return null;
        }
        String serlNum = "";
        serlNum = String.valueOf(Math.abs(UUID.randomUUID().toString().hashCode()));
        //【14位】
        String nowStr = LocalDateUtil.getNowDateStr(LocalDateUtil.TOTAL_DATE_TIME_SIMPLE);
        String strTemp = nowStr + serlNum;
        int strTempLength = strTemp.length();
        if (strTempLength >= length) {
            serlNum = strTemp.substring(0, length);
        } else if (strTempLength < length) {
            serlNum = strTemp + getStringRandom(length - strTempLength);
        }
        return serlNum;
    }

    /**
     * 新 创建订单号方法  使用当前时间+雪花数
     * @return
     */
    public static String getSnowOrderNo() {
        return SnowflakeUtil.getSnowflakeByDate(IdTypeEnum.ORDER);
    }

    /**
     * @param count
     * @param spilt
     * @return
     */
    public static String getSnowOrderNos(int count, String spilt) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < count; i++) {
            stringBuilder = stringBuilder.append(getSnowOrderNo()).append(spilt);
        }
        String result = stringBuilder.substring(0, stringBuilder.lastIndexOf(spilt) - 1);
        return result;
    }

    /**
     * 生成随机数字和字母(大小写)
     * @param length
     * @return
     * 2016年11月2日 下午4:13:39
     */
    public static String getStringRandom(int length) {
        String baseChar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        StringBuilder sb = new StringBuilder(length);
        if (length < 1) {
            length = 1;
        }
        int baseLength = baseChar.length();
        for (int i = 0; i < length; ++i) {
            int number = StringUtil.getThreadLocalRandom().nextInt(baseLength);
            sb.append(baseChar.charAt(number));
        }

        return sb.toString();

    }


    /**
     * 生成随机数字和大写字母
     * @param length
     * @return
     * 2016年11月2日 下午4:13:39
     */
    public static String getStringRandomByUpperCase(int length) {
        String baseChar = "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789";
        StringBuilder sb = new StringBuilder(length);
        if (length < 1) {
            length = 1;
        }
        int baseLength = baseChar.length();
        for (int i = 0; i < length; ++i) {
            int number = StringUtil.getThreadLocalRandom().nextInt(baseLength);
            sb.append(baseChar.charAt(number));
        }

        return sb.toString();
    }

    /**
     * 【优化】生成随机数字和字母
     * @param length
     * @return
     * 2017年7月18日 下午5:53:16
     */
    public static String getRandomString(int length) {
        StringBuilder sb = new StringBuilder();
        SecureRandom random = new SecureRandom();
        int randomNum = 0;
        for (int i = 0; i < length; i++) {
            randomNum = random.nextInt(100) % 2 == 0 ? 65 : 97;
            sb.append((char) (random.nextInt(26) + randomNum));
        }
        return sb.toString();
    }

    /**
     * 字符串前补零直到最大长度
     * @param
     * @return
     */
    public static String addZeroToStr(String str, int totalLength) {
        StringBuilder stringBuilder = new StringBuilder();
        int recycleCount = totalLength - str.length();
        for (int i = 0; i < recycleCount; i++) {
            stringBuilder.append(0);
        }
        return stringBuilder.toString() + str;
    }

    /**
     * 获得【指定长度的】随机数字符串
     * @param length
     * @return
     */
    public static String getRandomStrByLength(int length) {
        SecureRandom random = new SecureRandom();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < length; i++) {
            stringBuilder.append(random.nextInt(10));
        }
        return stringBuilder.toString();
    }

    /**
     * 生成指定长度的随机数，可重复
     * @param length
     * @return
     */
    public static String getNumByLength(int length) {
        int realLength = length - 1;
        int a = Double.valueOf((Math.random() * 9 + 1) * Math.pow(10, realLength)).intValue();
        return String.valueOf(a);
    }

    /**
     * 裁剪内容
     * @param content
     * @param cutLength
     * @return
     * 2017年3月2日 下午3:17:05
     */
    public static String cutContent(String content, int cutLength) {
        if (cutLength >= content.length()) {
            return content;
        } else {
            return content.substring(0, cutLength) + "...";
        }
    }

    /**
     * 获得参数map
     * @param queryStr
     * @return
     * 2017年5月16日 上午11:14:04
     */
    public static Map<String, String> getQueryStrMap(String queryStr) {
        String[] paramArrayInside = null;
        Map<String, String> paramMap = new HashMap<String, String>(20);
        if (queryStr.indexOf("&") >= 0) {
            String[] paramArray = queryStr.split("&");
            String param = "";
            for (int i = 0; i < paramArray.length; i++) {
                param = paramArray[i];
                if (param.indexOf("=") >= 0) {
                    paramArrayInside = param.split("=");
                    if (paramArrayInside != null && paramArrayInside.length == 2) {
                        paramMap.put(paramArrayInside[0], paramArrayInside[1]);
                    }
                }
            }
        } else {
            if (queryStr.indexOf("=") >= 0) {
                String[] paramArray = queryStr.split("=");
                if (paramArray != null && paramArray.length == 2) {
                    paramMap.put(paramArray[0], paramArray[1]);
                }
            }
        }
        return paramMap;
    }

    public static String getStr(String value, String defaultValue) {
        if (ValidateUtil.validateStrNullValue(value)) {
            return defaultValue;
        }
        return value;
    }

    /**
     * map转字符串
     * @param map
     * @param joinStr 拼接字符串
     * @return
     */
    public static String mapToStr(Map<String, String> map, String joinStr) {
        StringBuffer sb = new StringBuffer();
        for (String st : map.keySet()) {
            sb.append(st).append("=").append(map.get(st)).append(joinStr);
        }
        sb = sb.delete(sb.lastIndexOf(joinStr), sb.length());
        return sb.toString();
    }

    /**
     * 将指定前后位替换成*号
     * @param str
     * @param index
     * @return
     */
    public static String formatStrByX(String str, int index) {
        try {
            String regex = "(\\w{" + index + "})(.*)(\\w{" + index + "})";
            Matcher m = Pattern.compile(regex).matcher(str);
            if (m.find()) {
                String rep = m.group(2);
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < rep.length(); i++) {
                    sb.append("*");
                }
                return str.replaceAll(rep, sb.toString());

            }
            return str;
        } catch (Exception e) {
//			e.printStackTrace();
            return str;
        }
    }

    final static String METHOD_SET = "set";
    final static String METHOD_GET = "get";

    /**
     * 笨方法：String s = "你要去除的字符串"; <br>
     * 1.去除空格：s = s.replace('\\s',''); <br>
     * 2.去除回车：s =s.replace('\n',''); 这样也可以把空格和回车去掉，其他也可以照这样做。<br>
     * 注：\n 回车 \t 水平制表符 \s空格 \r 换行
     *
     * @param str
     * @return
     */
    public static String replaceBlank(String str) {
        String dest = "";
        if (str != null) {
            Pattern p = Pattern.compile(REPLACE_BLANK_REGEX);
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }

    /**
     * 将特殊字符转义再切分
     *
     * @param source
     * @param spliter
     * @return
     */
    public static String[] splitStr2Array(String source, String spliter) {

        String regex = spliter;
        if (regex.equals("?") || regex.equals("*") || regex.equals(")") || regex.equals("(") || regex.equals("{") || regex.equals("$") || regex.equals("+") || regex.equals(".") || regex.equals("|")) {

            regex = "[" + regex + "]";
        }

        return source.split(regex);
    }

    /**
     * 将byte[] 转换成字符串
     *
     * @param
     * @return
     */
    public static String byte2Hex(byte[] srcBytes) {
        StringBuilder hexRetSB = new StringBuilder();
        for (byte b : srcBytes) {
            String hexString = Integer.toHexString(0x00ff & b);
            hexRetSB.append(hexString.length() == 1 ? 0 : "").append(hexString);
        }
        return hexRetSB.toString();
    }

    /**
     * 将16进制字符串转为转换成字符串
     *
     * @param source
     * @return
     */
    public static byte[] hex2Bytes(String source) {
        byte[] sourceBytes = new byte[source.length() / 2];
        for (int i = 0; i < sourceBytes.length; i++) {
            sourceBytes[i] = (byte) Integer.parseInt(source.substring(i * 2, i * 2 + 2), 16);
        }
        return sourceBytes;
    }

    /**
     * ThreadLocalRandom
     * @return
     */
    public static ThreadLocalRandom getThreadLocalRandom() {
        return ThreadLocalRandom.current();
    }

    public static void main(String[] args) {

    }

    /**
     * 将字母转为数字
     * @param letter
     * @return
     */
    public static int letterToNumber(String letter) {
        int length = letter.length();
        int num = 0;
        int number = 0;
        for (int i = 0; i < length; i++) {
            char ch = letter.charAt(length - i - 1);
            num = (int) (ch - 'A' + 1);
            num *= Math.pow(26, i);
            number += num;
        }
        return Math.abs(number);
    }

    /**
     * workerId暂按默认填写.后续改为数据库读取,不同应用不同.
     * 雪花数生成方法,
     * @return
     */
    public static synchronized long getSnowflakeCouponCode() {
        return  SnowflakeUtil.getSnowflake(IdTypeEnum.COUPON_CODE);
    }
    /**
     *
     * 过滤字符串只剩下汉字 字母 数字
     * 
     * @Date 4:47 下午 2020/10/6
     * @param str
     * @return
     **/
    public static String StringFilter(String str) {
        if(StrUtil.isNotEmpty(str)){
            str = str.replaceAll("[^(a-zA-Z0-9\\u4e00-\\u9fa5)]", "");
        }
        return str;
    }

    /**
     * 字符串追加拼接
     *
     * 
     * @Date 5:16 下午 2020/10/20
     * @param
     * @param args
     * @return
     **/
    public static String StringAppend(String... args) {
        StringBuilder strBuilder = new StringBuilder();
        for (String str : args) {
            if (StrUtil.isNotEmpty(str)) {
                strBuilder.append("|").append(str);
            }
        }
        return strBuilder.toString();
    }

    /**
     * 随机生成带*手机号码
     */
    private static String[] telFirst="134,135,136,137,138,139,150,151,152,157,158,159,130,131,132,155,156,133,153,".split(",");
    public static List<String> getTel(Integer num) {
        List<String> telList=new ArrayList<>(num);
        for(int i=0;i<num;i++){
            int index=getNum(0,telFirst.length-1);
            String first=telFirst[index];
            String third=String.valueOf(getNum(1,9100)+10000).substring(1);
            telList.add(first+"****"+third);
        }
        return telList;
    }

    public static int getNum(int start,int end) {
        return (int)(Math.random()*(end-start+1)+start);
    }

    /**
     * 大写首字母
     * @param val
     * @return
     */
    public static String upperCaseFirst(String val) {
        char[] arr = val.toLowerCase().toCharArray();
        arr[0] = Character.toUpperCase(arr[0]);
        return new String(arr);
    }
}
